package com.hsj.common.gateway.handler;

import com.alibaba.fastjson2.JSON;
import com.hsj.common.gateway.constants.Constants;
import com.hsj.common.core.exception.HsjBaseException;
import com.hsj.common.core.exception.UnauthorizeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class GlobalExceptionHandler implements ErrorWebExceptionHandler {
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        log.error("接口调用异常：{}", ex.getMessage(), ex);

        ServerHttpResponse originalResponse = exchange.getResponse();
        Map<String, Object> ret = new HashMap<>();
        try {
            originalResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
            if (ex instanceof UnauthorizeException) {
                ret.put(Constants.CODE, ((HsjBaseException) ex).getErrorCode());
                ret.put(Constants.MSG, ex.getMessage());
            } else if (ex instanceof HsjBaseException) {
                ret.put(Constants.CODE, ((HsjBaseException) ex).getErrorCode());
                ret.put(Constants.MSG, ex.getMessage());
            } else {
                ret.put(Constants.CODE, "9999");
                ret.put(Constants.MSG, "系统异常");
            }
        }catch(Exception e){
            ret.put(Constants.CODE, "9999");
            ret.put(Constants.MSG, "系统异常");
        }
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();
        byte[] bytes = JSON.toJSONString(ret).getBytes(StandardCharsets.UTF_8);
        originalResponse.getHeaders().setContentLength(bytes.length);
        return originalResponse.writeWith(Flux.just(bufferFactory.wrap(bytes)));
    }
}
